﻿using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using MQ.Core.Common;
using Dapper;
using System.Data.SqlClient;
using System;
using System.Threading.Tasks;
using MQ.Core.Db.SqlServer;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;

namespace MQ.Core.Db
{
    public class BaseDb : IBaseDb
    {
        private readonly IDbConnection db;
        private readonly DbContext context;
        public BaseDb(IDbConnection db, DbContext context)
        {
            this.db = db;
            this.context = context;
        }
        #region base
        public string GetConnectionString()
        {
            return "";
        }
        #endregion

        #region  查询数据
        public bool Exist(string sql)
        {
            return db.ExecuteScalar<int>(sql) > 0;
        }
        public bool Exist(string sql, object param = null)
        {
            return db.ExecuteScalar<int>(sql, param) > 0;
        }
        public T GetObject<T>(string sql)
        {
            return db.ExecuteScalar<T>(sql);
        }
        public T GetObject<T>(string sql, object param = null)
        {
            return db.ExecuteScalar<T>(sql, param);
        }
        public T GetEntity<T>(string sql)
        {
            return db.QueryFirstOrDefault<T>(sql);
        }
        public T GetEntity<T>(string sql, object param = null)
        {
            return db.QueryFirstOrDefault<T>(sql, param);
        }
        public IEnumerable<T> GetList<T>(string sql)
        {
            return db.Query<T>(sql);
        }
        public IEnumerable<T> GetList<T>(string sql, object param = null)
        {
            return db.Query<T>(sql, param);
        }
        public IEnumerable<T> GetList<T>(string sql, Pagination pagination, object param = null)
        {
            return db.QueryPagination<T>(pagination, sql,param);
        }
        public DataTable GetList(string sql, object param = null)
        {
            var dt = new DataTable();
            var reader = db.ExecuteReader(sql, param);
            dt.Load(reader);
            return dt;
        }
        public DataTable GetList(string sql, Pagination pagination, object param = null)
        {
            return db.QueryPagination(pagination,sql,param);
        }
        #endregion

        #region  提交数据
        public int Execute(string sql, object param = null)
        {
            return db.Execute(sql);
        }
        public int ExecuteProc(string sql, object param = null)
        {
            return db.Execute(sql, param, null, null, CommandType.StoredProcedure);
        }
        public int Insert<T>(T entity) where T : class
        {
            context.Add<T>(entity);
            return context.SaveChanges();
        }
        public int Update<T>(T entity) where T : class
        {
            context.Update(entity);
            return context.SaveChanges();
        }

        public Task<T> GetObjectAsync<T>(string sql)
        {
            return db.QueryFirstAsync<T>(sql);
        }

        public Task<T> GetObjectAsync<T>(string sql, object param = null)
        {
            return db.QueryFirstAsync<T>(sql,param);
        }

        public Task<T> GetEntityAsync<T>(string sql, object param = null)
        {
            return db.QueryFirstAsync<T>(sql, param);
        }

        public Task<IEnumerable<T>> GetListAsync<T>(string sql)
        {
            return db.QueryAsync<T>(sql);
        }

        public Task<IEnumerable<T>> GetListAsync<T>(string sql, object param = null)
        {
            return db.QueryAsync<T>(sql,param);
        }

        public Task<IEnumerable<T>> GetListAsync<T>(string sql, Pagination pagination, object param = null)
        {
            return db.QueryPaginationAsync<T>(pagination,sql,param);
        }

        public async Task<DataTable> GetListAsync(string sql, object param = null)
        {
            var dt = new DataTable();
            var reader =await db.ExecuteReaderAsync(sql, param);
            dt.Load(reader);
            return dt;
        }

        public Task<DataTable> GetListAsync(string sql, Pagination pagination, object param = null)
        {
            return db.QueryPaginationAsync(pagination,sql,param);
        }

        public Task<int> ExecuteAsync(string sql, object param = null)
        {
            return db.ExecuteAsync(sql,param);
        }

        public Task<int> ExecuteProcAsync(string sql, object param = null)
        {
            return db.ExecuteAsync(sql, param, null, null, CommandType.StoredProcedure);
        }

        public Task<int> InsertAsync<T>(T entity) where T : class
        {
            context.AddAsync(entity);
            return context.SaveChangesAsync();
        }

        public Task<int> UpdateAsync<T>(T entity) where T : class
        {
            context.Update(entity);
            return context.SaveChangesAsync();
        }

        public int Delete<T>(T entity) where T : class
        {
            context.Remove(entity);
            return context.SaveChanges();
        }

        public Task<int> DeleteAsync<T>(T entity) where T : class
        {
            context.Remove(entity);
            return context.SaveChangesAsync();
        }
        public Task Transaction(Action action)
        {
            Action a = action;
            a();
            return Task.CompletedTask;
        }
        public IEnumerable<T> GetList<T>(Expression<Func<T, bool>> expression) where T : class
        {
            return context.Set<T>().Where(expression).ToList();
        }
        #endregion
    }
}
